<template>
    <el-tabs type="border-card">
        <!-- 文本处理工具 -->
        <el-tab-pane>
            <!-- 自定义标签页标题 -->
            <template #label>
                <div class="custom-tabs-label">
                    <el-icon><TextAnnotationToggle /></el-icon>
                    <span>文本处理工具</span>
                </div>
            </template>
            <!-- 自定义标签页内容 -->
            <div>
                <el-button class="mb-2" type="primary" :icon="TextClearFormat" @click="clearTextAreaEvent">清空</el-button>

                <!-- 文本域1 -->
                <el-input v-model="textarea1" :rows="15" type="textarea" placeholder="请输入待处理内容" />
                <!-- 按钮组 -->
                <div class="h-12 flex items-center">
                    <!-- 多行数据去重 -->
                    <el-button type="primary" text :icon="RepeatOnce" @click="MultiRowDataDeduplication">多行数据去重</el-button>
                    <!-- 空格处理 -->
                    <el-dropdown @command="handleSpaceCommand">
                        <el-button style="margin: 0 12px" type="primary" text :icon="Space">空格处理</el-button>
                        <template #dropdown>
                            <el-dropdown-menu>
                                <el-dropdown-item command="removeSpaces">去除所有空格</el-dropdown-item>
                                <el-dropdown-item command="removeLeftSpaces">去除第一个空格的左侧内容</el-dropdown-item>
                                <el-dropdown-item command="removeRightSpaces">去除第一个空格的右侧内容</el-dropdown-item>
                            </el-dropdown-menu>
                        </template>
                    </el-dropdown>
                    <!-- 提取产品尺寸 -->
                    <el-button type="primary" text :icon="AltRouteFilled" @click="extractProductSize">提取产品尺寸</el-button>
                    <!-- 保留偶数行 -->
                    <el-button type="primary" text :icon="Number1" @click="keepEvenRows">保留偶数行</el-button>
                    <!-- 保留奇数行 -->
                    <el-button type="primary" text :icon="Number2" @click="keepOddRows">保留奇数行</el-button>
                    <!-- 自定义分隔符 -->
                    <el-input style="width: 120px; margin-left: 12px" v-model="customSeparatorInput" placeholder="输入分隔符" />
                    <el-button type="primary" text :icon="FieldStringOutlined" @click="customSeparator">自定义分隔</el-button>
                </div>
                <!-- 文本域2 -->
                <el-input v-model="textarea2" :rows="15" type="textarea" placeholder="请选择处理的按钮" />
            </div>
        </el-tab-pane>
        <!-- 格式处理工具 -->
        <el-tab-pane>
            <!-- 自定义标签页标题 -->
            <template #label>
                <div class="custom-tabs-label">
                    <el-icon><TextAnnotationToggle /></el-icon>
                    <span>格式处理工具</span>
                </div>
            </template>
            <!-- 自定义标签页内容 -->
            <div>
                <!-- json转excel -->
                <el-button class="mb-2" type="primary" @click="jsonToExcel">JSON 转 Excel</el-button>
                <!-- excel转json -->
                <el-button class="mb-2" type="primary" @click="excelToJson">Excel 转 JSON</el-button>
                <!-- 用于上传 Excel 文件 -->
                <el-upload
                    class="upload-excel"
                    ref="upload"
                    action="#"
                    list-type="text"
                    drag
                    accept=".xlsx,.xls,.json"
                    :limit="1"
                    :auto-upload="false"
                    :on-exceed="handleExceed"
                    :on-change="handleFileChange"
                >
                    <el-icon class="el-icon--upload"><upload-filled /></el-icon>
                    <div class="el-upload__text">拖拽文件到此处或 <em>点击上传</em></div>
                    <template #tip>
                        <div class="el-upload__tip">excel/json 文件</div>
                    </template>
                </el-upload>
                <!-- 显示转换后的 JSON 数据 -->
                <el-input v-model="jsonData" :rows="15" type="textarea" placeholder="转换后的 JSON 数据" />
            </div>
        </el-tab-pane>
    </el-tabs>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { genFileId, UploadFile, UploadFiles, UploadInstance, UploadProps, UploadRawFile } from 'element-plus';
import { UploadFilled } from '@element-plus/icons-vue';
import { TextAnnotationToggle, TextClearFormat } from '@vicons/carbon';
import { RepeatOnce, Space } from '@vicons/tabler';
import { Number1, Number2 } from '@vicons/carbon';
import { AltRouteFilled } from '@vicons/material';
import { FieldStringOutlined } from '@vicons/antd';
import * as XLSX from 'xlsx';

/* ******************************文本处理工具属性/方法****************************** */
// 输入文本1
const textarea1 = ref('');
// 输出文本2
const textarea2 = ref('');

// 清空文本域
const clearTextAreaEvent = () => {
    textarea1.value = '';
    textarea2.value = '';
};

// 多行数据去重
const MultiRowDataDeduplication = () => {
    // 清空输出文本域
    textarea2.value = '';
    // 换行正则
    const reg = new RegExp('\n', 'g');
    // 保留非空数据
    const process = textarea1.value.split(reg).filter((item: string) => item !== '');
    // 去重
    Array.from(new Set(process)).map((item: string, index: number) => {
        // 最后一个添加不换行
        if (index === new Set(process).size - 1) {
            textarea2.value += item;
        } else {
            textarea2.value += item + '\n';
        }
    });
};

// 去除空格处理
const handleSpaceCommand = (command: string) => {
    // 清空输出文本域
    textarea2.value = '';
    if (command === 'removeSpaces') {
        // 去除所有空格不去除换行符
        textarea2.value = textarea1.value.replace(/ +/g, '');
    } else if (command === 'removeLeftSpaces') {
        // 先将每行变成数组
        const lines = textarea1.value.split('\n');
        // 去除第一个空格的左侧内容
        lines.forEach((line: string, index: number) => {
            const lineArray = line.split(/ +/);
            // 去除第一个空格的左侧内容
            lineArray.shift();
            lines[index] = lineArray.join(' ');
        });
        // 合并数组
        textarea2.value = lines.join('\n');
    } else if (command === 'removeRightSpaces') {
        // 先将每行变成数组
        const lines = textarea1.value.split('\n');
        // 去除第一个空格的右侧内容
        lines.forEach((line: string, index: number) => {
            const lineArray = line.split(/ +/);
            // 去除第一个空格的右侧内容
            lineArray.pop();
            lines[index] = lineArray.join(' ');
        });
        // 合并数组
        textarea2.value = lines.join('\n');
    }
};

// 提取产品尺寸
const extractProductSize = () => {
    // 清空输出文本域
    textarea2.value = '';
    // 提取产品尺寸正则
    const reg = new RegExp(/\d{1,4}[*]\d{1,4}[*]{0,1}\d{0,4}/g);
    // 只需要正则的内容
    const matches = textarea1.value.match(reg);
    if (matches) {
        textarea2.value = matches.join('\n');
    } else {
        textarea2.value = '未找到产品尺寸';
    }
};

// 保留偶数行
const keepEvenRows = () => {
    // 清空输出文本域
    textarea2.value = '';
    // 换行正则
    const reg = new RegExp('\n', 'g');
    // 保留非空数据
    const process = textarea1.value.split(reg).filter((item: string) => item !== '');
    // 保留偶数行
    process
        .filter((_item: string, index: number) => index % 2 === 0)
        .map((item: string, index: number) => {
            // 最后一个添加不换行
            if (index === process.filter((_item: string, index: number) => index % 2 === 0).length - 1) {
                textarea2.value += item;
            } else {
                textarea2.value += item + '\n';
            }
        });
};

// 保留奇数行
const keepOddRows = () => {
    // 清空输出文本域
    textarea2.value = '';
    // 换行正则
    const reg = new RegExp('\n', 'g');
    // 保留非空数据
    const process = textarea1.value.split(reg).filter((item: string) => item !== '');
    // 保留奇数行
    process
        .filter((_item: string, index: number) => index % 2 !== 0)
        .map((item: string, index: number) => {
            // 最后一个添加不换行
            if (index === process.filter((_item: string, index: number) => index % 2 !== 0).length - 1) {
                textarea2.value += item;
            } else {
                textarea2.value += item + '\n';
            }
        });
};

// 自定义分隔符
const customSeparatorInput = ref('');
// 自定义分隔符处理
const customSeparator = () => {
    // 清空输出文本域
    textarea2.value = '';
    // 逐行处理
    const lines = textarea1.value.split('\n');
    // 处理每一行
    lines.forEach((line: string, index: number) => {
        // 每一行匹配自定义分隔符并替换为制表符
        line = line.replaceAll(customSeparatorInput.value, '\t');
        // 最后一个添加不换行
        if (index === lines.length - 1) {
            textarea2.value += line;
        } else {
            textarea2.value += line + '\n';
        }
    });
};

/* ******************************格式处理工具属性/方法****************************** */
// upload实例
const upload = ref<UploadInstance>();
// 存储上传的文件
const parseFile = ref<File | null>(null);
// 覆盖前一个文件
const handleExceed: UploadProps['onExceed'] = (files) => {
    upload.value!.clearFiles();
    const file = files[0] as UploadRawFile;
    file.uid = genFileId();
    upload.value!.handleStart(file);
};
// 处理文件上传
const handleFileChange: UploadProps['onChange'] = (uploadFile: UploadFile, _uploadFiles: UploadFiles) => {
    // 检查文件类型是否为 Excel/Json 文件
    if (
        uploadFile.raw?.type !== 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' &&
        uploadFile.raw?.type !== 'application/vnd.ms-excel' &&
        uploadFile.raw?.type !== 'application/json'
    ) {
        ElMessage({
            message: '请上传 Excel/Json 文件',
            type: 'warning',
            grouping: true,
        });
        return;
    }

    parseFile.value = uploadFile.raw;
};

// JSON 转 Excel
const jsonToExcel = async () => {
    // 检查文件类型是否为 JSON 文件
    if (parseFile.value?.type !== 'application/json') {
        ElMessage({
            message: '请上传 JSON 文件',
            type: 'warning',
            grouping: true,
        });
        return;
    }

    try {
        // 读取文件内容
        const fileContent = await parseFile.value.text();
        const json = JSON.parse(fileContent);
        const worksheet = XLSX.utils.json_to_sheet(json);
        const workbook = XLSX.utils.book_new();
        XLSX.utils.book_append_sheet(workbook, worksheet, 'Sheet1');
        XLSX.writeFile(workbook, 'data.xlsx');
    } catch (error) {
        ElMessage({
            message: 'JSON 解析失败',
            type: 'error',
            grouping: true,
        });
    }
};

// 转换后的 JSON 数据
const jsonData = ref('');
// Excel 转 JSON
const excelToJson = async () => {
    // 检查文件类型是否为 Excel 文件
    if (
        parseFile.value?.type !== 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' &&
        parseFile.value?.type !== 'application/vnd.ms-excel'
    ) {
        ElMessage({
            message: '请上传 Excel 文件',
            type: 'warning',
            grouping: true,
        });
        return;
    }

    try {
        const fileReader = new FileReader();
        fileReader.onload = (e) => {
            const data = new Uint8Array(e.target?.result as ArrayBuffer);
            const workbook = XLSX.read(data, { type: 'array' });
            const firstSheetName = workbook.SheetNames[0];
            const worksheet = workbook.Sheets[firstSheetName];
            const json = XLSX.utils.sheet_to_json(worksheet);
            jsonData.value = JSON.stringify(json, null, 2);
        };
        fileReader.readAsArrayBuffer(parseFile.value);
    } catch (error) {
        ElMessage({
            message: 'Excel 解析失败',
            type: 'error',
            grouping: true,
        });
    }
};
</script>

<style scoped lang="scss">
.custom-tabs-label {
    .el-icon {
        vertical-align: middle;
    }
    span {
        vertical-align: middle;
        margin-left: 4px;
    }
}
.upload-excel {
    margin-top: 10px;
}
</style>
